package main

import (
	"fmt"
	"github.com/bogem/id3v2"
	"github.com/schollz/progressbar/v3"
	"io"
	"io/ioutil"
	"os"
)

type Music struct {
	Name     string // 歌曲名字
	URL      string // 下载地址
	AlbumPic string // 专辑封面
	Album    string // 专辑名称
	Singer   string // 歌手名称
}

type MusicStruct interface {
	getName() string
	getAlbumName() string
	getPic() string
	getDownloadURL() string
	getSinger() string
}

// 下载音乐
func (m *Music) download() {
	m.downloadMusic()
	m.downloadPic()
	// 合并音乐文件
	m.merge()
}

// 下载音乐
func (m *Music) downloadMusic() {
	response := Get(m.URL)
	defer response.Body.Close()
	out, err := os.Create(config.SaveDir + string(os.PathSeparator) + m.Name + ".mp3")
	if err != nil {
		fmt.Println("歌曲文件创建失败", err)
	}

	bar := progressbar.DefaultBytes(
		response.ContentLength,
		"Downloading MP3 "+m.Name+":",
	)
	_, _ = io.Copy(io.MultiWriter(out, bar), response.Body)

}

// 下载封面
func (m *Music) downloadPic() {
	response := Get(m.AlbumPic)
	defer response.Body.Close()
	out, err := os.Create(config.SaveDir + string(os.PathSeparator) + m.Name + ".jpg")
	if err != nil {
		fmt.Println("封面文件创建失败", err)
	}

	bar := progressbar.DefaultBytes(
		response.ContentLength,
		"Downloading AlbumPic "+m.Name+":",
	)
	_, _ = io.Copy(io.MultiWriter(out, bar), response.Body)
}

// 写入封面合并文件
func (m *Music) merge() {
	// 获取音乐信息
	mp3Path := config.SaveDir + string(os.PathSeparator) + m.Name + ".mp3"
	mp3Img := config.SaveDir + string(os.PathSeparator) + m.Name + ".jpg"

	tags, err := id3v2.Open(mp3Path, id3v2.Options{
		Parse: true,
	})
	// 统一编码设置 避免写入标签信息失败
	tags.SetDefaultEncoding(id3v2.EncodingUTF8)
	defer tags.Close()

	if err != nil {
		fmt.Println("合并文件失败", err)
		return
	}

	tags.SetAlbum(m.Album)
	tags.SetArtist(m.Singer)
	tags.SetTitle(m.Name)
	err = tags.Save()
	if err != nil {
		fmt.Println("标签信息插入失败", err)
	}

	picFrame, err := createPicFrame(mp3Img)
	if err != nil {
		return
	}
	// 将封面插入歌曲
	tags.AddAttachedPicture(picFrame)
	err = tags.Save()
	if err != nil {
		fmt.Println("插入封面失败", err)
	}
}

// 创建封面
func createPicFrame(mp3Img string) (picFrame id3v2.PictureFrame, err error) {
	albumData, err := ioutil.ReadFile(mp3Img)
	if err != nil {
		return
	}

	defer os.Remove(mp3Img)
	// 创建封面信息
	picFrame = id3v2.PictureFrame{
		Encoding:    id3v2.EncodingUTF8,
		MimeType:    "image/jpeg",
		PictureType: id3v2.PTFrontCover,
		Picture:     albumData,
	}
	return picFrame, nil
}
